package com.yzkj.cpjxc.business.service.impl;

import com.yzkj.cpjxc.business.framework.common.BusinessMap;
import com.yzkj.cpjxc.business.framework.common.Constants;
import com.yzkj.cpjxc.business.framework.common.Pager;
import com.yzkj.cpjxc.business.framework.utils.CollectionHelp;
import com.yzkj.cpjxc.business.framework.utils.IDUtils;
import com.yzkj.cpjxc.business.constants.SecurityMgrConstants;
import com.yzkj.cpjxc.business.domain.ZTreeComm;
import com.yzkj.cpjxc.business.constants.SysAuthorityConstants;
import com.yzkj.cpjxc.business.domain.SysAuthority;
import com.yzkj.cpjxc.business.domain.SysAuthorityQueryVo;
import com.yzkj.cpjxc.business.domain.SysAuthorityShowVo;
import com.yzkj.cpjxc.business.service.SysAuthorityService;
import com.yzkj.cpjxc.business.domain.SysRole;
import com.yzkj.cpjxc.business.service.SysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**权限事务管理实现类
 */
@Service
public class SysAuthorityServiceImpl implements SysAuthorityService {

	public Logger log = Logger.getLogger(SysAuthorityServiceImpl.class);
	
	/**
	 * MyBatis 命名空间
	 */
	private final static String MAPPER_NAMESPACE = "com.chkj.sysMgr.securityMgr.sysAuthority.mappers.SysAuthorityMapper";
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	@Autowired
	private SysRoleService sysRoleService;

	@Override
	public BusinessMap create(SysAuthority sa) throws Exception {
		BusinessMap bm = new BusinessMap();
		
		//如果系统终已存在顶级权限(顶级权限父级ID为空)，那么不能再添加父级ID为空的权限
		SysAuthority topLevelSysAuthority = this.getTopLevelSysAuthority();
		if(topLevelSysAuthority!= null && StringUtils.isBlank(sa.getParentId())){
			bm.put(Constants.WARNING_MSG, "当前新增权限必须选择一个父级权限节点");
			return bm;
		}
		//判断是否非法加入没有存在的父级权限ID
		if(StringUtils.isNotBlank(sa.getParentId())){
			SysAuthority satemp = this.getById(sa.getParentId());
			if(satemp == null){
				bm.put(Constants.WARNING_MSG, "选择的父级权限节点不存在!");
				return bm;
			}
		}
		
		//1、初始化id。
		if (StringUtils.isBlank(sa.getAuthorityId())) {
			sa.setAuthorityId(IDUtils.genUUID());
		}
		// 2、设置层级代码
		// 2.1	如果没有父级部门编号，就是代表着业务系统，那么层级代码为它本身，业务系统权限值不能重覆
		if (StringUtils.isBlank(sa.getParentId())) {
			//2.1.2、判断是否存在系统
			if (isExistsSystem(sa)) {
				bm.put(Constants.WARNING_MSG, SysAuthorityConstants.SYSTEM_EXISTS);
				return bm;
			}
			sa.setLevelCode(sa.getAuthorityId());
		} else {
			//3、获得父级权限
			SysAuthority parentSa = this.getById(sa.getParentId());
			//3.1 、获得levelCode第一层，就是业务系统
			String[] parentLevelCode = parentSa.getLevelCode().split("-");
			//3.2 、如果有父级部门编号,那么同一个系统内的权限值不能重覆,不同系统的权限值可以一样
			sa.setLevelCode(parentLevelCode[0]);
			if (isExists(sa)) {
				bm.put(Constants.WARNING_MSG, SysAuthorityConstants.AUTHORITY_EXISTS);
				return bm;
			}
			// 3.3	 如果有父级部门编号，那么取父级部门的层级代码加 它本身 
			if (parentSa != null) {
				sa.setLevelCode(parentSa.getLevelCode() + "-" + sa.getAuthorityId());
			}
		}
		sqlSessionTemplate.insert(MAPPER_NAMESPACE + ".add", sa);
		//4、每新增一条数据，给超级管理员添加权限
		Map<String, String> map = new HashMap<String, String>();
		//4.1、根据内置静态角色名（admin）,查詢admin的roleId。注意，admin角色必須存在且唯一。
		
		SysRole sr = sysRoleService.getRoleByRoleName(Constants.ADMIN);
		//4.2、如果返回的值不为空，则做操作.为空则保存失败
		if (sr != null) {
			map.put("roleId", sr.getRoleId());
			map.put("authorityId", sa.getAuthorityId());
			sqlSessionTemplate.insert(SecurityMgrConstants.ROLE_AUTHORITY_MAPPER_NAMESPACE + ".add", map);
		} else {
			bm.put(Constants.ERROR_MSG, Constants.SAVE_ERROR);
		}
		sqlSessionTemplate.flushStatements();
		return bm;
	}

	@Override
	public boolean isExists(SysAuthority sa) throws Exception {
		return (Integer) sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".isExists", sa) > 0;
	}

	@Override
	public SysAuthority getById(String sysAuthorityId) throws Exception {
		return sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getById", sysAuthorityId);
	}

	@Override
	public BusinessMap edit(SysAuthority sa) throws Exception {
		BusinessMap bm = new BusinessMap();
		
		// 不能修改顶级权限的权限值和上级权限(顶级权限没有上级权限，要保证顶级权限唯一)
		SysAuthority sat = this.getById(sa.getAuthorityId());
		if(sat != null){
			if(SysAuthorityConstants.DJ_AUTH_VALUE.equals(sat.getAuthorityValue()) && !SysAuthorityConstants.DJ_AUTH_VALUE.equals(sa.getAuthorityValue())){
				bm.put(Constants.WARNING_MSG, "无权限修改顶级权限值！");
				return bm;
			}
			if(StringUtils.isBlank(sat.getParentId()) && StringUtils.isNotBlank(sa.getParentId())){
				bm.put(Constants.WARNING_MSG, "无权限修改顶级权限的上级权限！");
				return bm;
			}
		}
		
		//1、判断系统权限是否已存在 ，同一个系统内的权限值不能重覆,不同系统的权限值可以一样
		String[] parentLevelCode = sat.getLevelCode().split("-");
		SysAuthority temp = new SysAuthority();
		BeanUtils.copyProperties(sa, temp, new String[] {
				"parentSysAuthority", "webAuthoritys"
		});
		temp.setLevelCode(parentLevelCode[0]);
		if (this.isExists(temp)) {
			bm.put(Constants.WARNING_MSG, SysAuthorityConstants.AUTHORITY_EXISTS);
			return bm;
		}
		
		//3、设置层级代码：因为编辑权限的时候，也有可能更改它的父节点
		if (StringUtils.isBlank(sa.getParentId())) {
			// 3.1、如果没有父级权限编号，那么层级代码为1
			sa.setLevelCode(sa.getAuthorityId());
		} else {
			// 3.2、如果有父级权限编号，那么取父级权限的层级代码加1
			SysAuthority parentSysAuthority = this.getById(sa.getParentId());
			if (parentSysAuthority != null) {
				String yuLevelCode= sat.getLevelCode();//原节点LevelCode
				String currLevelCode = parentSysAuthority.getLevelCode();//当前父节点LevelCode
				if (StringUtils.contains(currLevelCode, yuLevelCode)) {//判断修改后的父节点是否属于原自节点或者是自己的子节点
					bm.put(Constants.WARNING_MSG, SysAuthorityConstants.CHILD_PARENT_ERROR);
					return bm;
				}
				sa.setLevelCode(currLevelCode + "-" + sa.getAuthorityId());
			}else{
				bm.put(Constants.WARNING_MSG, "无效父节点权限！");
				return bm;
			}
		}
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".edit", sa);
		sqlSessionTemplate.flushStatements();
		
		return bm;
	}
	
	@Override
	public boolean deleteByLevelCode(String levelCode) throws Exception {
		// 物理删除角色权限关系数据
		sqlSessionTemplate.delete(SecurityMgrConstants.ROLE_AUTHORITY_MAPPER_NAMESPACE + ".deleteByLevelCode", levelCode);
		// 物理删除权限
		sqlSessionTemplate.delete(MAPPER_NAMESPACE + ".deleteByLevelCode", levelCode);
		return true;
	}

	@Override
	public boolean delete(String sysAuthorityId) throws Exception {
		// 删除角色权限关系数据
		sqlSessionTemplate.delete(SecurityMgrConstants.ROLE_AUTHORITY_MAPPER_NAMESPACE + ".deleteByAuthorityId", sysAuthorityId);
		// 删除权限
		sqlSessionTemplate.delete(MAPPER_NAMESPACE + ".deleteById", sysAuthorityId);
		return true;
	}

	@Override
	public Pager<SysAuthorityShowVo> search(Pager<SysAuthorityShowVo> pager, SysAuthority sa) throws Exception {
		if (!pager.isNeedPage()) {
			List<SysAuthority> list = sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".page", sa);
			List<SysAuthorityShowVo> dataList = new ArrayList<SysAuthorityShowVo>();
			// 2.1、判断是否为空
			if (CollectionHelp.isNotBank(list)) {
				SysAuthorityShowVo showVo = null;
				SysAuthority parentSa = null;
				for (SysAuthority saTemp : list) {
					showVo = new SysAuthorityShowVo();
					BeanUtils.copyProperties(saTemp, showVo, new String[] {
							"parentSysAuthority", "sysAuthoritys"
					});
					parentSa = saTemp.getParentSysAuthority();
					showVo.setParentAuthorityName(parentSa == null ? "" : parentSa.getAuthorityName());
					dataList.add(showVo);
				}
			}
			pager.setDataList(dataList);
			return pager;
		}

		List<SysAuthority> list = sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".page", sa, new RowBounds((pager.getCurrentPage() - 1) * pager.getLimit(), pager.getLimit()));
		// 2、根据分页数据重新组装成页面要展示的数据（SysAuthorityShowVo）
		List<SysAuthorityShowVo> dataList = new ArrayList<SysAuthorityShowVo>();
		// 2.1、判断是否为空
		if (CollectionHelp.isNotBank(list)) {
			SysAuthorityShowVo showVo = null;
			SysAuthority parentSysAuthority = null;
			for (SysAuthority saTemp : list) {
				showVo = new SysAuthorityShowVo();
				BeanUtils.copyProperties(saTemp, showVo, new String[] {
						"parentSysAuthority", "sysAuthoritys"
				});
				parentSysAuthority = saTemp.getParentSysAuthority();
				showVo.setParentAuthorityName(parentSysAuthority == null ? "" : parentSysAuthority.getAuthorityName());
				dataList.add(showVo);
			}
		}
		pager.setDataList(dataList);
		
		Long total = sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getTotal", sa);
		pager.setTotal(total);
		return pager;
	}


	@Override
	public boolean isExistsSystem(SysAuthority sa) throws Exception {
		return (Integer) sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".isExistsSystem", sa) > 0;
	}
	
	@Override
	public List<SysAuthority> getSysAuthoritysByUserId(String sysUserId) throws Exception {
		return sqlSessionTemplate.selectList(MAPPER_NAMESPACE+".getSysAuthoritysByUserId",sysUserId);
	}

	@Override
	public List<SysAuthority> getSysAuthoritysByRoleId(String sysRoleId) throws Exception {
		return sqlSessionTemplate.selectList(MAPPER_NAMESPACE+".getSysAuthoritysByRoleId",sysRoleId);
	}

	@Override
	public List<ZTreeComm> getAllChildByLevelCode(String levelCode) throws Exception {
		return sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".getAllChildByLevelCode", levelCode);
	}

	@Override
	public List<SysAuthority> queryByCondition(SysAuthorityQueryVo queryVo) throws Exception {
		return sqlSessionTemplate.selectList(MAPPER_NAMESPACE + ".queryByCondition", queryVo);
	}

	@Override
	public void initData() throws Exception {
		SysAuthorityQueryVo sVo = new SysAuthorityQueryVo();
		sVo.setStatus(Constants.STATUS_ACTIVE);
		List<SysAuthority> list = this.queryByCondition(sVo);
		if (CollectionHelp.isBank(list)) {
			
			SysAuthority sa = new SysAuthority();
			
			sa.setAuthorityId(IDUtils.genUUID());
			sa.setAuthorityName("数据库展示系统");
			sa.setAuthorityType(SysAuthorityConstants.AUTH_TYPE_MENU);
			sa.setAuthorityValue(SysAuthorityConstants.DJ_AUTH_VALUE);
			sa.setGrade("1");
			sa.setLevelCode(sa.getAuthorityId());
			sa.setParentId(null);
			sa.setRemark("数据库展示系统");
			sa.setSortNo("1");
			sa.setStatus(Constants.STATUS_ACTIVE);
			
			log.info("初始化权限数据-------------------------------------------------------------------------------------");
			this.create(sa);
		}
		
		
	}

	@Override
	public SysAuthority getTopLevelSysAuthority() throws Exception {
		return sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".getTopLevelSysAuthority");
	}

	@Override
	public BusinessMap editChildStatusByLevelCode(SysAuthority sau) throws Exception {
		BusinessMap bm = new BusinessMap();
		// 更改子类启用 停用状态
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".editChildStatusByLevelCode", sau);
		return bm;
	}

	@Override
	public BusinessMap editChildStatusId(List<String> listIds) throws Exception {
		BusinessMap bm = new BusinessMap();
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("listIds", listIds);

		// 更改子类启用 停用状态
		sqlSessionTemplate.update(MAPPER_NAMESPACE + ".editChildStatusId", map);
		return bm;
	}

	@Override
	public boolean isHavaChilds(String levelCode) throws Exception {
		return (Integer) sqlSessionTemplate.selectOne(MAPPER_NAMESPACE + ".isHavaChilds", levelCode) > 1;
	}
	
}
